package com.hsogoo.ultraman.monitor;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import com.hsogoo.ultraman.Constant;

import lombok.extern.slf4j.Slf4j;

/**
 * Created by za-huangsaigang on 2018/9/12.
 */
@Slf4j
public class ZkClient {

    private static class ZkClientHolder{
        private static final ZkClient instance = new ZkClient();
    }
    private static AtomicBoolean isRegistered = new AtomicBoolean(false);

    private static CuratorFramework client = null;

    private ZkClient(){}

    public synchronized static ZkClient getInstance(String url){
        if (client == null) {
            client = CuratorFrameworkFactory.builder()
                    .connectString(url)
                    .sessionTimeoutMs(1000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    .build();
            client.start();
        }
        return ZkClientHolder.instance;
    }

    /**
     * 创建根目录
     */
    public void createRootPath() {
        try {
            Stat stat = client.checkExists().forPath(Constant.CONFIG_ROOT_PATH);
            if (stat == null) {
                client.create().withMode(CreateMode.PERSISTENT).forPath(Constant.CONFIG_ROOT_PATH);
            }
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 创建节点
     * @param path
     * @param mode
     */
    public void createNode(String path, CreateMode mode) {
        try {
            if (mode == CreateMode.EPHEMERAL) {
                for (int i = 1; i <= 30; i++) {
                    Stat stat = client.checkExists().forPath(path);
                    if (stat == null) {
                        client.create().creatingParentsIfNeeded().withMode(mode).forPath(path);
                        isRegistered.compareAndSet(false, true);
                        break;
                    }else if (!isRegistered.get()){
                        //第一次注册的时候需要处理临时节点消失延迟问题，检测30s
                        Thread.sleep(1000);
                        log.info("注册节点中..." + path);
                    }else{
                        return;
                    }
                }
            } else {
                Stat stat = client.checkExists().forPath(path);
                if (stat == null) {
                    client.create().creatingParentsIfNeeded().withMode(mode).forPath(path);
                }
            }
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 写数据：/zookeeper/app
     * @param path
     * @param content
     * @throws Exception
     */
    public void write(String path,String content) throws Exception {
        Stat stat = client.checkExists().forPath(path);
        if (stat == null) {
            client.create().creatingParentsIfNeeded()
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(path, content.getBytes("utf-8"));
        }else {
            client.setData().forPath(path, content.getBytes("utf-8"));
        }
    }

    public String read(String path) throws Exception {
        byte[] b = client.getData().forPath(path);
        String value = new String(b, "utf-8");
        return value;
    }

    public List<String> getAllServer() {
        try {
            return client.getChildren().forPath(Constant.CONFIG_SERVER_LIST);
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }


}
